﻿using Koala.Pro.Common.Extension;
using Koala.Pro.Common;
using Koala.Pro.Services;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Koala.Pro.Core.Models;

namespace Koala.Pro.Controls
{
    public partial class MenuControl : UserControl
    {
        private bool isInit;

        public static readonly DependencyProperty MenuInfosProperty = DependencyProperty.Register("MenuInfos", typeof(List<MenuInfo>), typeof(MenuControl));

        public static readonly DependencyProperty SelectItemProperty = DependencyProperty.Register("SelectItem", typeof(MenuInfo), typeof(MenuControl));

        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MenuControl), new FrameworkPropertyMetadata("上级菜单", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(MenuControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValuePropertyChanged));

        public static readonly DependencyProperty ValueChangedCommandProperty = DependencyProperty.Register("ValueChangedCommand", typeof(ICommand), typeof(MenuControl), new PropertyMetadata((object)null));

        public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(MenuControl));

        public static readonly RoutedEvent ValueChangedEvent;

        public List<MenuInfo> MenuInfos
        {
            get
            {
                return (List<MenuInfo>)GetValue(MenuInfosProperty);
            }
            set
            {
                SetValue(MenuInfosProperty, value);
            }
        }

        public MenuInfo SelectItem
        {
            get
            {
                return (MenuInfo)GetValue(SelectItemProperty);
            }
            set
            {
                SetValue(SelectItemProperty, value);
            }
        }

        public string Text
        {
            get
            {
                return (string)GetValue(TextProperty);
            }
            set
            {
                SetValue(TextProperty, value);
            }
        }

        public string? Value
        {
            get
            {
                return (string)GetValue(ValueProperty);
            }
            set
            {
                SetValue(ValueProperty, value);
            }
        }

        public ICommand ValueChangedCommand
        {
            get
            {
                return (ICommand)GetValue(ValueChangedCommandProperty);
            }
            set
            {
                SetValue(ValueChangedCommandProperty, value);
            }
        }

        public object CommandParameter
        {
            get
            {
                return GetValue(CommandParameterProperty);
            }
            set
            {
                SetValue(CommandParameterProperty, value);
            }
        }

        public event RoutedEventHandler ValueChanged
        {
            add
            {
                AddHandler(ValueChangedEvent, value);
            }
            remove
            {
                RemoveHandler(ValueChangedEvent, value);
            }
        }

        public MenuControl()
        {
            InitializeComponent();
        }

        protected override async void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            await Init();
        }

        public async Task Init()
        {
            if (!isInit && !this.IsInDesignMode())
            {
                MenuInfos = await GetMenuInfos();
                isInit = true;
            }
        }

        private static async Task<List<MenuInfo>> GetMenuInfos()
        {
            new List<MenuInfo>();
            string systemType = App.ViewModel.SystemType;
            List<MenuInfo> list = ((!App.ViewModel.IsSuperAdmin) ? (await BLLFactory<IMenuService>.Instance.GetMenuNodesByUser(App.ViewModel.UserInfo.Id, systemType)) : (await BLLFactory<IMenuService>.Instance.GetTree(systemType)));
            list.Insert(0, new MenuInfo
            {
                Name = "顶级目录",
                Id = "-1"
            });
            return list;
        }

        private static async void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is MenuControl control) || control == null)
            {
                return;
            }
            string oldValue = e.OldValue?.ToString();
            string newValue = e.NewValue?.ToString();
            if (!newValue.IsNullOrEmpty())
            {
                if (!control.isInit)
                {
                    await control.Init();
                }
                List<MenuInfo> list = control.MenuInfos?.FindMenuNodes((MenuInfo s) => s.Id == newValue);
                if (list != null && list.Count > 0 && list[0] != null)
                {
                    control.SelectItem = list[0];
                }
                RoutedPropertyChangedEventArgs<string> routedPropertyChangedEventArgs = new RoutedPropertyChangedEventArgs<string>(oldValue, newValue, ValueChangedEvent);
                control.RaiseEvent(routedPropertyChangedEventArgs);
                control.ValueChangedCommand?.Execute(newValue);
            }
        }

        private void TreeComboBox_SelectedItemChanged(object sender, RoutedEventArgs e)
        {
            MenuInfo selectItem = SelectItem;
            if (selectItem != null && Value != selectItem.Id.ToString())
            {
                Value = selectItem.Id.ToString();
            }
        }

        static MenuControl()
        {
            ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChangedEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MenuControl));
        }
    }
}
